##################################################################
# File : /lua/ui/controls/commandmode.lua
# Description : Manages the current command mode, which determines what action
#				the mouse will take when next clicked in the world
# Author : GPG
##################################################################

local Dragger = import('/lua/maui/dragger.lua').Dragger
local UIMain = import('/lua/ui/uimain.lua')
local UIUtil = import('/lua/ui/uiutil.lua')
local Orders = import('/lua/ui/game/orders.lua')
local Common = import('/lua/common/CommonUtils.lua')
--[[
 THESE TABLES ARE NOT ACTUALLY USED IN SCRIPT. Just here for reference

 # these are the strings which represent a command mode
 commandModes = {
     "order",
     "select",
     "cancel",
 }

 these strings come from the cpp code in UnitBP, don\'t change them please!
 orderModes = {

    // Common rules
    RULEUCC_Move                = (1 << 0),
    RULEUCC_AggressiveMove      = (1 << 1),
    RULEUCC_Stop                = (1 << 2),
    RULEUCC_Attack              = (1 << 3),
    RULEUCC_Guard               = (1 << 4),
    RULEUCC_Patrol              = (1 << 5),
    RULEUCC_RetaliateToggle     = (1 << 6),

    // Unit specific rules
    RULEUCC_Repair              = (1 << 7),
    RULEUCC_Capture             = (1 << 8),
    RULEUCC_Pause               = (1 << 9),
    RULEUCC_SpecialAction       = (1 << 10),

    // Unit general script
    RULEUCC_Script              = (1 << 11),

    // Used to generate an invalid cursor for out of range or cannot attack cases
    RULEUCC_Invalid             = (1 << 12),
 }
--]]

local commandMode = false
local modeData = false
local issuedOneCommand = false
local canVO = true

function OnCommandModeBeat()
	if issuedOneCommand and not IsKeyDown('Shift') then
		EndCommandMode(true)
	end
end

function StartCommandMode(newCommandMode, data)
    if commandMode then
        EndCommandMode(false)
    end

    UIMain.AddEscapeHandler(EndCommandMode, UIUtil.ESCPRI_Commands)

    commandMode = newCommandMode
    modeData = data

    if modeData then
        if modeData.HighlightMode then
            import('/lua/ui/game/worldview.lua').SetHighlightMode(modeData.HighlightMode)
        elseif modeData == "RULEUCC_Attack" then
            import('/lua/ui/game/worldview.lua').SetHighlightMode("FavorEnemy")
        elseif modeData == "RULEUCC_Guard" then
            import('/lua/ui/game/worldview.lua').SetHighlightMode("FavorAlly")
        end
    end
end

function GetCommandMode()
    return {commandMode, modeData}
end

function EndCommandMode(clearModifier)
    #LOG('EndCommandMode ', clearModifier)

    UIMain.RemoveEscapeHandler(EndCommandMode)

    # Favor enemies by default for right clicking since we're usually attacking
    import('/lua/ui/game/worldview.lua').SetHighlightMode("FavorEnemy")

    commandMode = false
    modeData = false
	issuedOneCommand = false
end

commandFeedbackResource = {
	Move = { Mesh = '/Meshes/game/Move_Mesh.gr2', Tex = '/Meshes/game/Move_albedo.dds', Sound = 'Forge/UI/Hud/snd_ui_hud_valid_move_click', }, #PLACEHOLDER
	InvalidMove = { Mesh = '/Meshes/game/Move_Mesh.gr2', Tex = '/Meshes/game/Move_albedo.dds', Sound = 'Forge/UI/Lobby/snd_ui_lobby_lobby_unique_fail', }, #PLACEHOLDER
	Attack = { Mesh = '/Meshes/game/Attack_Mesh.gr2', Tex = '/Meshes/game/Attack_albedo.dds', },
	Guard = { Mesh = '/Meshes/game/Assist_Mesh.gr2', Tex = '/Meshes/game/Assist_albedo.dds', },
	Capture = { Mesh = '/Meshes/game/Capture_Mesh.gr2', Tex = '/Meshes/game/Capture_albedo.dds', },
	Patrol = { Mesh = '/Meshes/game/Patrol_Mesh.gr2', Tex = '/Meshes/game/Patrol_albedo.dds', },
	Repair = { Mesh = '/Meshes/game/Repair_Mesh.gr2', Tex = '/Meshes/game/Repair_albedo.dds', },
}


function AddCommandFeedbackByType(pos, type)

	if commandFeedbackResource[type] == nil then
		return false;
	else
		AddCommandFeedbackBlip({
					Position = pos,
					MeshName = commandFeedbackResource[type].Mesh,
					TextureName = commandFeedbackResource[type].Tex,
					ShaderName = 'CommandFeedback',
					UniformScale = 0.125,
				}, 0.7)
		if commandFeedbackResource[type].Sound then
		    PlaySound( commandFeedbackResource[type].Sound )
		end

	end

	return true;
end

function OnCommandIssued(command)

    #special case: If the only unit selected is immobile and the command is a move order,
    #play a fail cue every time.
    local unitCount = table.getsize(command.Units)
    if unitCount == 1 and command.CommandType == 'Move' and command.Units[1]:IsImmobile() then
         PlaySound( commandFeedbackResource['InvalidMove'].Sound )
    else
        if canVO then
    	    for k, unit in command.Units do
    	        if EntityCategoryContains(categories.HERO, unit) then
    	            local ctype = command.CommandType
    	            local syncData = Common.GetSyncData(unit)
    	            local charBP = syncData.CharacterBP
    	            local sound = false

                    if ctype == 'Script' and command.LuaParams and command.LuaParams.AbilityName then
    	                local abil = command.LuaParams.AbilityName
    	                if charBP.VO[abil] and charBP.VO[abil].Sound then
                            sound = charBP.VO[abil].Sound
                        end
    	            else
    	                if charBP.VO[ctype] and charBP.VO[ctype].Sound then
                            sound = charBP.VO[ctype].Sound
                        end
                    end

                    if sound then
                        PlaySound(sound)
                        canVO = false
                        ForkThread(ResetCanVOThread)
                        break
                    end
    	        end
    	    end
        end
    end

    if not command.Clear then
		issuedOneCommand = true
	else
		EndCommandMode(true)
	end



	if command.CommandType == 'Ability' then
        Orders.OnTargetAbilityUsed(command)
    else
		if AddCommandFeedbackByType(command.Target.Position, command.CommandType) == false then

			AddCommandFeedbackBlip({
				Position = command.Target.Position,
				MeshName = '/meshes/game/crosshair02d_mesh.gr2',
				TextureName = '/meshes/game/crosshair02d_albedo.dds',
				ShaderName = 'CommandFeedback',
				UniformScale = 0.75,
			}, 0.75)
		end
	end
end

function ResetCanVOThread()
    WaitSeconds(5)
    canVO = true
end

function Init()
    import('/lua/ui/game/gamemain.lua').BeatCallback:Add(OnCommandModeBeat)
end